package de.lulusoft.anothertorrent.gui.views;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;

import de.lulusoft.anothertorrent.core.AnotherTorrentCore;
import de.lulusoft.anothertorrent.core.rtorrent.Torrent;
import de.lulusoft.anothertorrent.core.rtorrent.View;
import de.lulusoft.anothertorrent.gui.AnotherTorrentGui;
import de.lulusoft.anothertorrent.gui.commands.ChangeTorrentPriorityCommand;
import de.lulusoft.anothertorrent.gui.commands.DeleteTorrentCommand;
import de.lulusoft.anothertorrent.gui.commands.TorrentRehashCommand;
//import de.lulusoft.anothertorrent.gui.commands.DownloadSetConnectionSeed;
import de.lulusoft.anothertorrent.gui.commands.StartTorrentCommand;
import de.lulusoft.anothertorrent.gui.commands.StopTorrentCommand;
import de.lulusoft.anothertorrent.gui.preferences.PreferenceConstants;
import de.lulusoft.anothertorrent.gui.util.Util;
import de.lulusoft.anothertorrent.gui.views.Providers.TableColumnSorter;
import de.lulusoft.anothertorrent.gui.views.Providers.TorrentDetailsViewInput;
import de.lulusoft.anothertorrent.gui.views.Providers.TorrentListViewContentProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.TorrentListViewInput;
import de.lulusoft.anothertorrent.gui.views.Providers.TorrentListViewLabelProvider;
import de.lulusoft.anothertorrent.gui.views.Providers.TorrentListViewPriorityEditingSupport;

public class TorrentListView extends ViewPart{
	
	public static final String ID = "de.lulusoft.anothertorrent.gui.views.TorrentListView";

	private static final String STATE_INPUT = "STATE_INPUT";
	
	private static final String[] properties = {"Name", "Status", "Done", 
		"Remain", "Size", "Down", "Up", "Seeded",
		"Ratio", "Peers", "Priority", "ETA", "Private", "PEX", "Connection type"};
	
	private TableViewer viewer = null;
	private Text viewerFilter = null;
	private Job timer = null;
	private long timerInterval = 1000;
	private View m_view = null;
	private TorrentListViewInput m_input = null;
	

	@Override
	public void dispose() {
		if (timer != null)
			timer.cancel();
		super.dispose();
	}

	public TorrentListView() {
		
	}
	
	@Override
	public void saveState(IMemento memento) {
		super.saveState(memento);
		ByteArrayOutputStream  os = new ByteArrayOutputStream();
		ObjectOutputStream oOut = null;
		try {
			oOut = new ObjectOutputStream(os);
			oOut.writeObject(m_input);
			oOut.flush();
			String tmp = Util.convertBytesToHex(os.toByteArray());
			memento.putString(STATE_INPUT, tmp);
		} catch (IOException e) {
			e.printStackTrace();
		} finally 
		{
			try {
				oOut.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}	

	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		if (memento == null)
			return;
		String state = memento.getString(STATE_INPUT);
		if (state != null)
		{
			try {
				byte bstate[] = Util.convertHexStringToBytes(state);
				ByteArrayInputStream is = new ByteArrayInputStream(bstate);
				ObjectInputStream ois = new ObjectInputStream(is);
				TorrentListViewInput input = (TorrentListViewInput) ois.readObject();
				input = new TorrentListViewInput(
						AnotherTorrentCore.getDefault().getServerManager().getServerByName(input.getServer().getName()),
						input.getViewName());
				this.m_input = input;
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void setInput(Object input)
	{
		if (input instanceof TorrentListViewInput
				&& !viewer.getTable().isDisposed())
		{
			try {
				m_input = (TorrentListViewInput)input;
				// Stop timer
				timer.cancel();
				// Set view name
				setPartName("View: " + m_input.getServer().getName() + "." + m_input.getViewName());
				// fetch view
				m_view = m_input.getServer().getRTorrentManager().getView(m_input.getViewName());
				viewer.setInput(m_view);
				// auto fit columns
				for (TableColumn tc : viewer.getTable().getColumns())
					tc.pack();
				// add timer
				 timer.schedule(timerInterval);
			} catch (Exception e) {
				IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not set input on TorrentListView", e);
				AnotherTorrentGui.getDefault().getLog().log(status );
				e.printStackTrace();
			}
			
		}
	}

	@Override
	public void createPartControl(Composite parent) {

		parent.setLayout(new GridLayout(1,true));
		GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false);
		Composite toolbar = new Composite(parent, SWT.FILL);
		toolbar.setLayoutData(gd);
		toolbar.setLayout(new RowLayout());
		
		Button cmdDelete = new Button(toolbar, SWT.PUSH);
		cmdDelete.setImage(AnotherTorrentGui.createImage("delete.png"));
		cmdDelete.setToolTipText("Delete Torrent(s) (not the contents on disk)");
		cmdDelete.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						try 
						{
							ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
							Command cmd = scmd.getCommand(DeleteTorrentCommand.ID);
							Map<String, String> params = new HashMap<String, String>();
							ExecutionEvent event = new ExecutionEvent(null, params, t, null);
							cmd.executeWithChecks(event);
						}
						catch (Exception e2) 
						{
							IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not delete torrent", e2);
							AnotherTorrentGui.getDefault().getLog().log(status );
							e2.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		
		Button cmdStop = new Button(toolbar, SWT.PUSH);
		cmdStop.setImage(AnotherTorrentGui.createImage("stop.png"));
		cmdStop.setToolTipText("Stop Torrent(s)");
		cmdStop.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						try 
						{
							ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
							Command cmd = scmd.getCommand(StopTorrentCommand.ID);
							Map<String, String> params = new HashMap<String, String>();
							ExecutionEvent event = new ExecutionEvent(null, params, t, null);
							cmd.executeWithChecks(event);
						}
						catch (Exception e2) 
						{
							IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not stop torrent", e2);
							AnotherTorrentGui.getDefault().getLog().log(status );
							e2.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
				
		Button cmdPlay = new Button(toolbar, SWT.PUSH);
		cmdPlay.setImage(AnotherTorrentGui.createImage("control_play_blue.png"));
		cmdPlay.setToolTipText("Start Torrent(s)");
		cmdPlay.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						try 
						{
							ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
							Command cmd = scmd.getCommand(StartTorrentCommand.ID);
							Map<String, String> params = new HashMap<String, String>();
							ExecutionEvent event = new ExecutionEvent(null, params, t, null);
							cmd.executeWithChecks(event);
						}
						catch (Exception e2) 
						{
							IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not start torrent", e2);
							AnotherTorrentGui.getDefault().getLog().log(status );
							e2.printStackTrace();
						}
					}
				}		
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		
		Button cmdRehash = new Button(toolbar, SWT.PUSH);
		cmdRehash.setImage(AnotherTorrentGui.createImage("arrow_refresh.png"));
		cmdRehash.setToolTipText("Rehash Torrent(s)");
		cmdRehash.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						try 
						{
							ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
							Command cmd = scmd.getCommand(TorrentRehashCommand.ID);
							Map<String, String> params = new HashMap<String, String>();
							ExecutionEvent event = new ExecutionEvent(null, params, t, null);
							cmd.executeWithChecks(event);
						}
						catch (Exception e2) 
						{
							IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not rehash torrent", e2);
							AnotherTorrentGui.getDefault().getLog().log(status );
							e2.printStackTrace();
						}
					}
				}		
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		
		final Menu mnuSetPrio = new Menu(toolbar.getParent().getShell(), SWT.POP_UP);
		MenuItem miOff = new MenuItem(mnuSetPrio, SWT.NONE);
		miOff.setText("Off");
		miOff.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(ChangeTorrentPriorityCommand.P_PRIORITY, "0");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miLow = new MenuItem(mnuSetPrio, SWT.NONE);
		miLow.setText("Low");
		miLow.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(ChangeTorrentPriorityCommand.P_PRIORITY, "1");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miNormal = new MenuItem(mnuSetPrio, SWT.NONE);
		miNormal.setText("Normal");
		miNormal.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(ChangeTorrentPriorityCommand.P_PRIORITY, "2");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miHigh = new MenuItem(mnuSetPrio, SWT.NONE);
		miHigh.setText("High");
		miHigh.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(ChangeTorrentPriorityCommand.P_PRIORITY, "3");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		
		final Button cmdSetPrio = new Button(toolbar, SWT.PUSH | SWT.DROP_DOWN);
		cmdSetPrio.setText("Set Priority");
		cmdSetPrio.addSelectionListener(new SelectionListener(){

			public void widgetDefaultSelected(SelectionEvent e) {}

			public void widgetSelected(SelectionEvent e) {
				if ( !mnuSetPrio.isVisible() ) {
					Rectangle bounds = cmdSetPrio.getBounds();
					Point menuLoc =
						cmdSetPrio.getParent().toDisplay(bounds.x, bounds.y + bounds.height);

					mnuSetPrio.setLocation(menuLoc.x, menuLoc.y);
					mnuSetPrio.setVisible(true);
				}
			}			
		});
		
		viewerFilter = new Text(toolbar, SWT.SINGLE | SWT.BORDER);
		viewerFilter.setToolTipText("Filter torrents by name");
		viewerFilter.addModifyListener(new ModifyListener() {
		
			@Override
			public void modifyText(ModifyEvent e) {
				final String filterText = viewerFilter.getText().toLowerCase();
				ViewerFilter filter = new ViewerFilter() {
					
					@Override
					public boolean select(Viewer viewer, Object parentElement, Object element) {
						if (element instanceof Torrent)
						{
							Torrent t = (Torrent)element;
							if (t.getName().toLowerCase().indexOf(filterText) != -1)
								return true;
						}
						return false;
					}
				};
				viewer.setFilters(new ViewerFilter[]{filter});		
			}
		});
		
		// Set Connection seed is not possible atm
//		final Menu mnuSetConnectionSeed = new Menu(toolbar.getParent().getShell(), SWT.POP_UP);
//		MenuItem miSeed = new MenuItem(mnuSetConnectionSeed, SWT.NONE);
//		miSeed.setText("seed");
//		miSeed.addSelectionListener(new SelectionListener() {
//			@SuppressWarnings("unchecked")
//			@Override
//			public void widgetSelected(SelectionEvent e) {
//				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
//				if(!sel.isEmpty())
//				{
//					Iterator<Torrent> it = sel.iterator();
//					while (it.hasNext())
//					{
//						Torrent t = it.next();
//						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
//						Command cmd = scmd.getCommand(DownloadSetConnectionSeed.ID);
//						Map<String, String> params = new HashMap<String, String>();
//						params.put(DownloadSetConnectionSeed.P_CONNECTION_SEED, DownloadSetConnectionSeed.P_SEED);
//						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
//						try {
//							cmd.executeWithChecks(event);
//						} catch (Exception e1) {
//							e1.printStackTrace();
//						}
//					}
//				}	
//			}
//			@Override
//			public void widgetDefaultSelected(SelectionEvent e) {}
//		});
//		MenuItem miInitialSeed = new MenuItem(mnuSetConnectionSeed, SWT.NONE);
//		miInitialSeed.setText("initial_seed");
//		miInitialSeed.addSelectionListener(new SelectionListener() {
//			@SuppressWarnings("unchecked")
//			@Override
//			public void widgetSelected(SelectionEvent e) {
//				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
//				if(!sel.isEmpty())
//				{
//					Iterator<Torrent> it = sel.iterator();
//					while (it.hasNext())
//					{
//						Torrent t = it.next();
//						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
//						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
//						Map<String, String> params = new HashMap<String, String>();
//						params.put(DownloadSetConnectionSeed.P_CONNECTION_SEED, DownloadSetConnectionSeed.P_INITIAL_SEED);
//						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
//						try {
//							cmd.executeWithChecks(event);
//						} catch (Exception e1) {
//							e1.printStackTrace();
//						}
//					}
//				}	
//			}
//			@Override
//			public void widgetDefaultSelected(SelectionEvent e) {}
//		});
//		
//		final Button cmdSetConnectionSeed = new Button(toolbar, SWT.PUSH | SWT.DROP_DOWN);
//		cmdSetConnectionSeed.setText("Set Connection Seed");
//		cmdSetConnectionSeed.addSelectionListener(new SelectionListener(){
//
//			public void widgetDefaultSelected(SelectionEvent e) {}
//
//			public void widgetSelected(SelectionEvent e) {
//				if ( !mnuSetConnectionSeed.isVisible() ) {
//					Rectangle bounds = cmdSetConnectionSeed.getBounds();
//					Point menuLoc =
//						cmdSetConnectionSeed.getParent().toDisplay(bounds.x, bounds.y + bounds.height);
//
//					mnuSetConnectionSeed.setLocation(menuLoc.x, menuLoc.y);
//					mnuSetConnectionSeed.setVisible(true);
//				}
//			}			
//		});
			
		
		Composite viewerComp = new Composite(parent, SWT.FILL | SWT.BORDER);
		gd = new GridData(SWT.FILL, SWT.FILL, true, true);
		viewerComp.setLayoutData(gd);
		viewerComp.setLayout(new FillLayout());
		viewer = new TableViewer(viewerComp,  SWT.FULL_SELECTION | SWT.MULTI);
		viewer.setColumnProperties(properties);
		viewer.getTable().setHeaderVisible(true);
		viewer.getTable().setLinesVisible(true);

		// add columns
		int i = 0;
		for (final String prop : properties)
		{
			final int colIdx = i;
			TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
			column.getColumn().setText(prop);
			column.getColumn().setWidth(100);
			column.getColumn().setMoveable(true);
			
			if (prop.equals("Priority"))
			{
				column.setEditingSupport(new TorrentListViewPriorityEditingSupport(viewer));
			}

			// Add Sorters..
			TableColumnSorter cSorter = new TableColumnSorter(viewer, column.getColumn()) 
			{
			     protected int doCompare(Viewer v, Object e1, Object e2) 
			     {
			    	 Torrent t1 = (Torrent)e1;
			    	 Torrent t2 = (Torrent)e2;
			    	 if (prop.equals("Remain"))
			    	 {
			    		return t1.getRemainingBytes().compareTo(t2.getRemainingBytes()); 
			    	 }
			    	 else if (prop.equals("Size"))
			    	 {
			    		return t1.getSize_bytes().compareTo(t2.getSize_bytes()); 
			    	 }
			    	 else if (prop.equals("Down"))
			    	 {
			    		return t1.getDown_rate().compareTo(t2.getDown_rate()); 
			    	 }
			    	 else if (prop.equals("Up"))
			    	 {
			    		return t1.getUp_rate().compareTo(t2.getUp_rate()); 
			    	 }
			    	 else if (prop.equals("Seeded"))
			    	 {
			    		return t1.getUp_total().compareTo(t2.getUp_total()); 
			    	 }
			    	 else if (prop.equals("Done"))
			    	 {
			    		return t1.getDonePercent().compareTo(t2.getDonePercent()); 
			    	 }
			    	 else if (prop.equals("Priority"))
			    	 {
			    		return t1.getPriority().compareTo(t2.getPriority()); 
			    	 }
			    	 else if (prop.equals("ETA"))
			    	 {
			    		return t1.getETA().compareTo(t2.getETA()); 
			    	 }
			    	 else
			    	 {
			             ITableLabelProvider lp = ((ITableLabelProvider) viewer
			            		 .getLabelProvider());
			             String s1 = lp.getColumnText(e1, colIdx);
			             String s2 = lp.getColumnText(e2, colIdx);
			             return s1.compareTo(s2);
			    	 }
			     }
			};

			cSorter.setSorter(cSorter, TableColumnSorter.ASC);
			i++;
		}
		viewer.setContentProvider(new TorrentListViewContentProvider());
		viewer.setLabelProvider(new TorrentListViewLabelProvider());
		viewer.addDoubleClickListener(new IDoubleClickListener() {
		
			@Override
			public void doubleClick(DoubleClickEvent event) {
				
				if (event.getSelection() instanceof IStructuredSelection)
				{
					IStructuredSelection s = (IStructuredSelection)event.getSelection();
					if (s.getFirstElement() instanceof Torrent)
					{
						Torrent t = (Torrent)s.getFirstElement();

						
						try 
						{
							TorrentDetailsView tv = (TorrentDetailsView)
								AnotherTorrentGui.getDefault()
								.getWorkbench().getActiveWorkbenchWindow()
								.getActivePage().showView(TorrentDetailsView.ID, 
										t.getName(), IWorkbenchPage.VIEW_ACTIVATE);
							tv.setInput(new TorrentDetailsViewInput(m_input.getServer(), t));
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}
				}
		
			}
		});
				
		// Create popup menu
		final Menu mnuContext = new Menu(viewer.getTable().getParent().getShell(), SWT.POP_UP);
		MenuItem itemStart = new MenuItem(mnuContext, SWT.NONE);
		itemStart.setText("Start Torrent(s)");
		itemStart.setImage(AnotherTorrentGui.createImage("control_play_blue.png"));
		itemStart.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						try 
						{
							ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
							Command cmd = scmd.getCommand(StartTorrentCommand.ID);
							Map<String, String> params = new HashMap<String, String>();
							ExecutionEvent event = new ExecutionEvent(null, params, t, null);
							cmd.executeWithChecks(event);
						}
						catch (Exception e2) 
						{
							IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not start torrent", e2);
							AnotherTorrentGui.getDefault().getLog().log(status );
							e2.printStackTrace();
						}
					}
				}		
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});		
		MenuItem itemStop = new MenuItem(mnuContext, SWT.NONE);
		itemStop.setText("Stop Torrent(s)");
		itemStop.setImage(AnotherTorrentGui.createImage("stop.png"));
		itemStop.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						try 
						{
							ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
							Command cmd = scmd.getCommand(StopTorrentCommand.ID);
							Map<String, String> params = new HashMap<String, String>();
							ExecutionEvent event = new ExecutionEvent(null, params, t, null);
							cmd.executeWithChecks(event);
						}
						catch (Exception e2) 
						{
							IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not stop torrent", e2);
							AnotherTorrentGui.getDefault().getLog().log(status );
							e2.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem itemDelete = new MenuItem(mnuContext, SWT.NONE);
		itemDelete.setText("Delete Torrent(s)");
		itemDelete.setImage(AnotherTorrentGui.createImage("delete.png"));
		itemDelete.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						try 
						{
							ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
							Command cmd = scmd.getCommand(DeleteTorrentCommand.ID);
							Map<String, String> params = new HashMap<String, String>();
							ExecutionEvent event = new ExecutionEvent(null, params, t, null);
							cmd.executeWithChecks(event);
						}
						catch (Exception e2) 
						{
							IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not delete torrent", e2);
							AnotherTorrentGui.getDefault().getLog().log(status );
							e2.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem itemRehash = new MenuItem(mnuContext, SWT.NONE);
		itemRehash.setText("Rehash Torrent(s)");
		itemRehash.setImage(AnotherTorrentGui.createImage("arrow_refresh.png"));
		itemRehash.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						try 
						{
							ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
							Command cmd = scmd.getCommand(TorrentRehashCommand.ID);
							Map<String, String> params = new HashMap<String, String>();
							ExecutionEvent event = new ExecutionEvent(null, params, t, null);
							cmd.executeWithChecks(event);
						}
						catch (Exception e2) 
						{
							IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not rehash torrent", e2);
							AnotherTorrentGui.getDefault().getLog().log(status );
							e2.printStackTrace();
						}
					}
				}		
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem itemPrioMenu = new MenuItem(mnuContext, SWT.CASCADE);
		itemPrioMenu.setText("Set Priority");
		Menu mnuContextPrio = new Menu(viewer.getTable().getParent().getShell(), SWT.DROP_DOWN);
		itemPrioMenu.setMenu(mnuContextPrio);
		MenuItem miContextPrioOff = new MenuItem(mnuContextPrio, SWT.NONE);
		miContextPrioOff.setText("Off");
		miContextPrioOff.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(ChangeTorrentPriorityCommand.P_PRIORITY, "0");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miContextPrioLow = new MenuItem(mnuContextPrio, SWT.NONE);
		miContextPrioLow.setText("Low");
		miContextPrioLow.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(ChangeTorrentPriorityCommand.P_PRIORITY, "1");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miContextPrioNormal = new MenuItem(mnuContextPrio, SWT.NONE);
		miContextPrioNormal.setText("Normal");
		miContextPrioNormal.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(ChangeTorrentPriorityCommand.P_PRIORITY, "2");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		MenuItem miContextPrioHigh = new MenuItem(mnuContextPrio, SWT.NONE);
		miContextPrioHigh.setText("High");
		miContextPrioHigh.addSelectionListener(new SelectionListener() {
			@SuppressWarnings("unchecked")
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();	
				if(!sel.isEmpty())
				{
					Iterator<Torrent> it = sel.iterator();
					while (it.hasNext())
					{
						Torrent t = it.next();
						ICommandService scmd = (ICommandService)getSite().getService(ICommandService.class);
						Command cmd = scmd.getCommand(ChangeTorrentPriorityCommand.ID);
						Map<String, String> params = new HashMap<String, String>();
						params.put(ChangeTorrentPriorityCommand.P_PRIORITY, "3");
						ExecutionEvent event = new ExecutionEvent(null, params, t, null);
						try {
							cmd.executeWithChecks(event);
						} catch (Exception e1) {
							e1.printStackTrace();
						}
					}
				}	
			}
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});
		viewer.getTable().setMenu(mnuContext);
		
		
		// create update timer
		timer = new Job("Updating Data for View...") {
			
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try
				{
					monitor.beginTask("Updating Data for View: " + m_input.getViewName() , IProgressMonitor.UNKNOWN);
					// Update Data
					try {
						m_input.getServer().getRTorrentManager().updateView(m_view);
					} catch (Exception e) {
						IStatus status = new Status(IStatus.ERROR, AnotherTorrentGui.PLUGIN_ID, "Could not update view", e);
						AnotherTorrentGui.getDefault().getLog().log(status );
						e.printStackTrace();
					}
					
					// Update Timer
					timerInterval = AnotherTorrentGui.getDefault()
						.getPreferenceStore().getInt(PreferenceConstants.P_UPDATE_INTERVAL_LIST_VIEW) * 1000;
					this.schedule(timerInterval);
					// Update UI
					UIJob ui = new UIJob(Display.getDefault(), "Updating View: " + m_input.getViewName()){

						@Override
						public IStatus runInUIThread(IProgressMonitor monitor) {
							try
							{
							monitor.beginTask("Updating View: " + m_input.getViewName() , IProgressMonitor.UNKNOWN);
							// Save current selection
							ISelection sel = viewer.getSelection();
							// Update View
							m_view.updateGUI();
							// Restore selection
							viewer.setSelection(sel, false);
							monitor.done();
							}
							catch (Exception e) {
								e.printStackTrace();
							}
							
							return Status.OK_STATUS;
						}
						
					};
					ui.schedule();
					monitor.done();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
				
				return Status.OK_STATUS;
				
			}
		};
		timer.setUser(false);
		timerInterval = AnotherTorrentGui.getDefault()
			.getPreferenceStore().getInt(PreferenceConstants.P_UPDATE_INTERVAL_LIST_VIEW) * 1000;
		
		// restore view if input is available
		if (this.m_input != null)
			this.setInput(this.m_input);
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}
	
	  public View getM_view() {
		return m_view;
	}

	

}
